﻿using System;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Soundteller.Application.Facade.Interfaces;

namespace Soundteller.Application.Components
{
    public class SoundtellerComponent : DrawableGameComponent
    {
        private IAudioVisualFacade _audioVisualFacade;
        private IVisualFacade _visualFacade;
        private SpriteBatch _spriteBatch;

        private readonly object _lock = new object();
        private bool _ignoreMouse;

        public SoundtellerComponent(Game game, IVisualFacade visualFacade, IAudioVisualFacade audioVisualFacade)
            : base(game)
        {
            if (visualFacade == null) throw new ArgumentNullException("visualFacade");
            if (audioVisualFacade == null) throw new ArgumentNullException("audioVisualFacade");

            _visualFacade = visualFacade;
            _audioVisualFacade = audioVisualFacade;
        }

        public override void Initialize()
        {
            Debug.WriteLine("{0}.Initialize()", GetType().Namespace, null);

            _audioVisualFacade.SubscribePadStateUpdater();
            _audioVisualFacade.SubscribePadStateResetter();

            base.Initialize();
        }

        protected override void LoadContent()
        {
            Debug.WriteLine("{0}.LoadContent()", GetType().Namespace, null);

            _spriteBatch = new SpriteBatch(GraphicsDevice);

            _audioVisualFacade.InitializeSoundteller(Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height);
        }

        public override void Update(GameTime gameTime)
        {
            HandleMouse();

            _audioVisualFacade.UpdateSoundteller();
        }

        public override void Draw(GameTime gameTime)
        {
            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

            while (_visualFacade.PeekGraphicBuffer() != null)
            {
                var graphic = _visualFacade.PopGraphicBuffer();
                _spriteBatch.Draw(graphic.Texture, graphic.ScreenCoordinates, graphic.SpriteTint);
            }

            _spriteBatch.End();
        }

        private void HandleMouse()
        {
            lock (_lock)
            {
                var mouseState = Mouse.GetState();
                switch (mouseState.LeftButton)
                {
                    case ButtonState.Pressed:
                        if (_ignoreMouse) return;

                        _ignoreMouse = true;
                        _audioVisualFacade.TouchPad(mouseState);
                        break;

                    case ButtonState.Released:
                        _ignoreMouse = false;
                        break;

                    default:
                        break;
                }
            }
        }
    }
}